<template>
  <div>
    <!-- v-model: 关联底部加载状态
      loading: true(转圈)
      loading: false(不再转圈)
      finished: 数据全都加载完成，
       --true: 加载完成后不再触发load事件 (底部显示finished-text的文字)
       --false: 触底继续触发load事件

      @load事件: 组件滚动底部时, 内部会调用load事件触发

      immediate-check:
       --true - 上来默认检查一次触底
       --false - 上来不检查触底
     -->
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list
        v-model="loading"
        :finished="finished"
        finished-text="没有更多了"
        :immediate-check="false"
        @load="onLoad"
      >
        <!-- <ArticleItem></ArticleItem> -->
        <!-- 除了使用大写，还可以使用以下格式的标签名组件 -->
        <article-item
          v-for="obj in articleList"
          :key="obj.art_id"
          :artObj="obj"
          @click.native="artDetailFn(obj.art_id)"
        ></article-item>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
/*
目标: 文章列表铺设
1. 找到接口, 写api/index.js->接口方法
2. ArticleList引入, 发起文章列表请求拿到数据
3. v-for遍历article-item, 传入数据对象展示数据
引入子组件ArticleItem.vue
*/

/*
组件套路
1. 找到类似的, 复制过来, 使用运行看效果
2. 删除无用的
3. 修改(读属性/直接改文字/标签数量)
4. 其他....
*/

/*
目标: 底部加载更多组件 (van-list)
重要1: 当组件滚动到底部时，会触发 load 事件并将 loading 设置成 true
重要2: finished: 加载完成，加载完成后不再触发load事件
重要3: 初始化的时候, 就判定是否触底(数据是网络请求回来的-异步, 默认触发load一次)
重要4: 数据加载完毕, loading: false(保证下次触底还能执行load事件)
注意：
  和tabs配合使用van-list小问题:
  复现: 前一页, 往下滚动, 然后再切换到别的频道, 会导致van-list上来又触发@load事件
  原因: :immediate-check无法阻止滚动事件的监听效果
  前一页, 网页滚动条滚动下边去了, tab下一页没有那么高(默认上来数据没回来, 没有滚动条的)
  滚动条从下边, 自己又滚动回来了
*/

/*
目标: 触底, 在发请求, 拿到下一页数据
1. 接口文档: 发现需要传递timestamp时间戳
下一页数据需要传递上一次接口返回的pre_timestamp的时间值
2. data函数里nextTime, 专门用于保存紧挨着的上一次的pre_timestamp的值
3. onLoad触底加载更多事件方法中, 把nextTime传入API接口方法内
4. 修改api/index.js相应接口, 接收timestamp值(不能固定的)
*/

/*
目标: 解决默认触发2次的bug, 解决加载更多数据
1. list组件immediate-check:false (关闭立即检查)
2. onLoad方法里, 要把新的数据和原数据, 进行合并(数据更多)
3. 异步加载完毕以后loading:false (保证下次触底还能执行load事件)
4. 判断没有更多数据了, finished: true(加载完成)
*/

/*
目标: 下拉刷新(顶部刷新)
js原生实现:
移动端特有事件名: touchstart touchmove touchend
获取手指在屏幕的坐标点, 移动后, 手指坐标点, 手指离开屏幕触发touchend
获取到手指偏移量, 修改标签的位移量 (加c3过渡动画)
采用PullRefresh的组件
1. 找到包在van-list组件外面
2. 把变量和方法定义好
3. 刷新方法里, 清空数组, 把nextTime=new Date(), 重新请求一次新的数据
4. refreshing的状态: false
*/

import ArticleItem from '@/components/ArticleItem.vue'
import { getArticleListAPI } from '@/api'
export default {
  data () {
    return {
      // 文章列表
      articleList: [],
      list: [],
      // 底部加载的状态
      loading: false,
      finished: false,
      // 下一页的文章列表-开头文章的发布时间(来自于上一次响应值里pre_timestamp)
      nextTime: new Date(),
      // 顶部刷新的状态
      refreshing: false
    }
  },
  props: {
    channelId: Number
  },
  // 只在这个页面使用，因此用局部注册即可
  components: {
    ArticleItem
  },
  // tab在切换的时候, 如果是第一次出现, 会走一次created
  // 切回去的时候created不走了, 但是标签没动(横向的位移)
  /*  async created () {
    const res = await getArticleListAPI(this.channelId)
    // console.log(res);
    this.articleList = res.data.data.results
  }, */
  methods: {
    async onLoad () {
      // 异步更新数据, 获取文章列表
      // const res = await getArticleListAPI({
      //   channel_id: this.channelId,
      //   timestamp: this.nextTime
      // })
      // 知识点: res.data.data可能是null, 如果继续.results就报错了
      // 你需要用逻辑与前置判断, 前面.出来值了, 才能继续往下.
      // 更好的做法:
      // if (res.data.data && res.data.data.results && res.data.data.results.length === 0) {
      //   // 本次加载更多就无数据
      //   this.finished = true
      // }
      // if (res.data?.data?.results?.length === 0) {
      //   // 本次加载更多就无数据
      //   this.finished = true
      // }

      // this.articleList = [...this.articleList, ...res.data.data.results]
      // this.loading = false // 本次加载完毕(这样下次触底, 才能再出发load事件和onLoad方法)
      if (this.articleList.length > 0) {
        // 上来先走created初始化请求，把数据拿回来铺设页面，等用户帧的滚动到下面了，再次执行onLoad事件，这个判断有数据了，再调用封装的获取文章列表的方法来请求下一页
        this.getArticleListFn()
      }
    },
    // 封装获取文章列表的方法
    async getArticleListFn () {
      const res = await getArticleListAPI({
        channel_id: this.channelId,
        timestamp: this.nextTime
      })
      /*       if (res.data?.data?.results?.length === 0) {
        // 本次加载更多就无数据
        this.finished = true
      } */
      // 这里使用...展开式等同于在articleList数组中追加加载出来的数据，而不是覆盖
      this.articleList = [...this.articleList, ...res.data.data.results]
      if (res.data?.data?.pre_timestamp === null) {
        this.finished = true
        this.nextTime = null
      } else {
        this.nextTime = res.data.data.pre_timestamp
      }
      // 本次加载完毕(这样下次触底, 才能再出发load事件和onLoad方法)
      this.loading = false
      // 使用定时器是为了看顶部转圈加载的效果
      setTimeout(() => {
        // 本次下拉刷新完毕
        this.refreshing = false
      }, 1000)
    },
    // 顶部刷新
    onRefresh () {
      // 刷新新的数据回来, 原数组清空
      // 再向后台发送一次请求, timestamp改回车最新的时间
      this.articleList = []
      this.timestamp = new Date()
      this.getArticleListFn()
    },
    artDetailFn (artId) {
      this.$router.push({
        path: '/art_detail',
        query: {
          // 文章id传到文章详情页
          aid: artId
        }
      })
    }
  },
  created () {
    // tab在切换的时候, 如果是第一次出现, 会走一次created
    // 切回去的时候created不走了, 但是标签没动(横向的位移)
    // res.data (axios内, 把后台返回的数据对象放到了data字段下)
    // 后台数据对象里, 还有个data, 所以需要.2次data
    this.getArticleListFn()
  }
}
</script>

<style></style>
